package com.liy.framework.common.jwt;

import java.security.spec.*;
import java.io.*;
import java.security.*;
import java.util.*;

public class RsaKeyHelper
{
    public PublicKey getPublicKey(final String filename) throws Exception {
        final InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(filename);
        final DataInputStream dis = new DataInputStream(resourceAsStream);
        final byte[] keyBytes = new byte[resourceAsStream.available()];
        dis.readFully(keyBytes);
        dis.close();
        final X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        final KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }
    
    public PrivateKey getPrivateKey(final String filename) throws Exception {
        final InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(filename);
        final DataInputStream dis = new DataInputStream(resourceAsStream);
        final byte[] keyBytes = new byte[resourceAsStream.available()];
        dis.readFully(keyBytes);
        dis.close();
        final PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        final KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }
    
    public PublicKey getPublicKey(final byte[] publicKey) throws Exception {
        final X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKey);
        final KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }
    
    public PrivateKey getPrivateKey(final byte[] privateKey) throws Exception {
        final PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKey);
        final KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }
    
    public void generateKey(final String publicKeyFilename, final String privateKeyFilename, final String password) throws IOException, NoSuchAlgorithmException {
        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        final SecureRandom secureRandom = new SecureRandom(password.getBytes());
        keyPairGenerator.initialize(1024, secureRandom);
        final KeyPair keyPair = keyPairGenerator.genKeyPair();
        final byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        FileOutputStream fos = new FileOutputStream(publicKeyFilename);
        fos.write(publicKeyBytes);
        fos.close();
        final byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
        fos = new FileOutputStream(privateKeyFilename);
        fos.write(privateKeyBytes);
        fos.close();
    }
    
    public static byte[] generatePublicKey(final String password) throws IOException, NoSuchAlgorithmException {
        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        final SecureRandom secureRandom = new SecureRandom(password.getBytes());
        keyPairGenerator.initialize(1024, secureRandom);
        final KeyPair keyPair = keyPairGenerator.genKeyPair();
        return keyPair.getPublic().getEncoded();
    }
    
    public static byte[] generatePrivateKey(final String password) throws IOException, NoSuchAlgorithmException {
        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        final SecureRandom secureRandom = new SecureRandom(password.getBytes());
        keyPairGenerator.initialize(1024, secureRandom);
        final KeyPair keyPair = keyPairGenerator.genKeyPair();
        return keyPair.getPrivate().getEncoded();
    }
    
    public static Map<String, byte[]> generateKey(final String password) throws IOException, NoSuchAlgorithmException {
        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        final SecureRandom secureRandom = new SecureRandom(password.getBytes());
        keyPairGenerator.initialize(1024, secureRandom);
        final KeyPair keyPair = keyPairGenerator.genKeyPair();
        final byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        final byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
        final Map<String, byte[]> map = new HashMap<String, byte[]>();
        map.put("pub", publicKeyBytes);
        map.put("pri", privateKeyBytes);
        return map;
    }
}
